/* 
 * File:   RapidMain.cpp
 * Author: dell
 * 
 * Created on 2012年5月11日, 下午1:45
 */

#include "RapidMain.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string>
#include <vector>
#include <ext/hash_set>
#include <sys/types.h>
#include <dirent.h>
#include <cerrno>
#include "common.h"

#include "RapidServer.h"
#include "ServerPid.h"
#include "RapidStopper.h"
#include <evhttp/resources.h>
#include <evhttp/log.h>
#include "FileCachedCleanServer.h"

using namespace std;

namespace Rapid{
    std::string RapidMain::homeDir = "";
    
    //RapidConfigManager rapidConfigManager;
    RapidMain::RapidMain() {
    }


    RapidMain::~RapidMain() {
    }
    
    void printHelp(){
        cout<<"******************** rapid web server help ****************************"<<endl;
        cout<<"./rapid <mode> <homedir> "<<endl;
        cout<<"mode: startup mode"<<endl;
        //cout<<"      run   - non-daemon mode"<<endl;
        cout<<"      start - daemon mode"<<endl;
        cout<<"      stop  - stop server"<<endl;
        cout<<"      kill  - kill server"<<endl;
        cout<<"      -h    - help me"<<endl;
        cout<<"homedir: service to configure the home directory"<<endl;

        //cout<<"server.xml: the service configuration file, the default will search the current directory or the conf directory, the default file name is server.xml"<<endl;
        //cout<<"global.xml: the global configuration file, the default will search the current directory or the conf directory or the installation directory, the default file name is global.xml"<<endl;
    }

    /**
    * 第一个参数为mode, 第二个参数为服务配置主目录
    */
    int RapidMain::main(int argc, char** argv) {
        
        string globalConfigFileName = "conf/global.xml";
        string serverConfigFileName = "conf/server.xml";

        if(argc < 3){
            cout<<"parameter error, --help or --h"<<endl;
            printHelp();
            return 1;
        }
        const char* startMode = argv[1];
        LOG_DEBUG("startMode:%s", startMode);

        //string homeDir(argv[2]);
        RapidMain::homeDir.assign(argv[2]);
        //检查最后一个字符是否"/", 如果不是，自动加上
        if(RapidMain::homeDir[RapidMain::homeDir.size()-1] != '/'){
            RapidMain::homeDir.append("/");
        }

        LOG_DEBUG("homeDir:%s", RapidMain::homeDir.c_str());

        bool isDaemon = false;
        if(strcmp(startMode, "start")==0){
            isDaemon = true;
    //    }else if(strcmp(startMode, "run")==0){ //此种模式有问题，是由于子进程会继承父进程的资源引起的，万恶
    //        isDaemon = false;
        }else if(strcmp(startMode, "stop")==0){
            return RapidStopper::stopAll(RapidMain::homeDir.c_str());
            
        }else if(strcmp(startMode, "kill")==0){
            return RapidStopper::killAll(RapidMain::homeDir.c_str());   
            
        }else if(strcmp(startMode, "-h")==0){         
            printHelp();
            return 0;
        }else{
            cout<<"parameter error, -h"<<endl;
            printHelp();
            return 1;
        }


        serverConfigFileName = string(RapidMain::homeDir).append(serverConfigFileName); //服务配置
        globalConfigFileName = string(RapidMain::homeDir).append(globalConfigFileName); //指定全局配置

        LOG_DEBUG("globalConfigFileName:%s", globalConfigFileName.c_str());
        LOG_DEBUG("serverConfigFileName:%s", serverConfigFileName.c_str());

        if(!rapidConfigManager.loadConfig(globalConfigFileName.c_str(), serverConfigFileName.c_str())){
            return 1;
        }

        
        //检查FileCachedClean进程是否存在
        if(existFileCachedCleanProcess(RapidMain::homeDir)){
            cout<<"server already is started!"<<endl;
            return 1;
        }
        
        vector<ServerConfig*>* serverConfigs = rapidConfigManager.getServerConfigs();
        LOG_DEBUG("serverConfigs->size():%d", serverConfigs->size());
        vector<ServerConfig*>::iterator scfgit = serverConfigs->begin();
        for(; scfgit != serverConfigs->end(); scfgit++){
            LOG_DEBUG("starting ... at port %d", (*scfgit)->port);
            RapidServer* rapidServer = new RapidServer(*scfgit, RapidMain::homeDir);
            rapidServer->start(isDaemon);
            allRapidServers.insert(rapidServer);   
        }

        AllRapidServers::iterator it = allRapidServers.begin();
        for(; it != allRapidServers.end();it++){
            delete *it;
        }
        allRapidServers.clear();
        
        //启动FileCached清理进程
        FileCachedCleanServer fileCachedCleanServer(&rapidConfigManager, RapidMain::homeDir);
        fileCachedCleanServer.start();
        
        if(!isDaemon){
            HttpServer::loop();
        }

        return 0;
    }
    
    
    
    bool RapidMain::existFileCachedCleanProcess(string& homeDir){
        ServerPid serverPid((homeDir+FILECACHED_CLEAN_PROCESS_FILENAME).c_str());
        if(serverPid.existFile()){
            if(serverPid.existProcess()){
                return true; 
            }else{
                serverPid.remove();
            }
        }        
        return false;
    }
}

